package cn.bonoon.kernel.expression;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import cn.bonoon.kernel.expression.resolver.AbstractExpressionPropertyResolver;
import cn.bonoon.kernel.expression.results.RequestExpressionValue;

/**
 * 关于表达式的解析的公共父类
 * @author jackson
 *
 */
public abstract class AbstractExpressionWrapper implements ExpressionParseContext, Iterable<ExpressionValue>{

	private final static char S = '{', E = '}';
	
	private final ExpressionPropertyResolver propertyResolver = AbstractExpressionPropertyResolver.factory();

	/** 解析后的完整的表达式，也有可能只是where部分；这个对象不能暴露在外面 */
	private final StringBuilder expression = new StringBuilder();

	/** 查询字段表达式的值 */
	private final List<ExpressionValue> values = new ArrayList<>();
	
	/** 这里表示在访问时，需要把这些参数从访问路径get/post过来；大部分是不需要的 */
	private List<QueryExpressionParameter> parameters;
	
	protected ExpressionPropertyResolver defaultPropertyResolver(){
		return propertyResolver;
	}
	
	@Override
	public Iterator<ExpressionValue> iterator() {
		return values.iterator();
	}
	
	public void value(ExpressionValue eValue){
		values.add(eValue);
	}
	
	/** 需要在访问路径里传递参数的，在生成界面的时候，需要按规则生成相应的参数传递的访问路径，get/post方式传递参数 */
	public void parameter(QueryExpressionParameter parameter){
		if(null != parameters) parameters = new ArrayList<>(2);
		parameters.add(parameter);
	}
	
	protected void internalParse(String query, ExpressionPropertyResolver propertyResolver)throws Exception{
		int i = 0;
		char[] chs = query.toCharArray();
		int ol = chs.length;
		while(i < ol - 1){
			char c0 = chs[i++];
			
			if(c0 == S){
				if(chs[i] == S){
					i++;
					expression.append(c0);
				}else{
					//需要替换的属性的开始位置
					int sp = i;
					
					while(i < ol && chs[i++] != E);
					//i为最近的一个'}'的位置
					int l = i - sp;
					if(i < ol || chs[i - 1] == E){
						l--;
					}
					if(l > 0){
						internalParseValue(new String(chs, sp, l).trim(), propertyResolver);
//						String valueExpression = new String(chs, sp, l).trim();
//						if(!expressionResolver.resolver(valueExpression, this)){
//							//这里是没有进行定义的表达式，则认为该值直接使用velocity进行赋值
//							values.add(new RequestExpressionValue(this, valueExpression));
//						}
					}//else 只有"{}"的情况或以"{"结束的情况
				}
			}else{
				if(c0 == E && chs[i] == E){
					i++;
				}
				expression.append(c0);
			}
		}
		
		while(i < ol){
			expression.append(chs[i++]);
		}
	}
	
	protected void internalParseValue(String valueExpression, ExpressionPropertyResolver propertyResolver)throws Exception{
		if(!propertyResolver.resolver(this, valueExpression)){
			//这里是没有进行定义的表达式，则认为该值直接使用velocity进行赋值
			values.add(new RequestExpressionValue(this, valueExpression));
		}
	}
	
	/** 查询语句需要使用到的查询条件，这些条件值通过表达式的计算来产生 */
	public ExpressionValue[] values() {
		return values.toArray(new ExpressionValue[values.size()]);
	}
	
	/** 用于界面上的处理，生成从界面到控制器的传递语句；可以为null值 */
	public List<QueryExpressionParameter> getParameters() {
		return parameters;
	}

	@Override
	public String toString() {
		return expression.toString();
	}

	public void append(String str) {
		expression.append(str);
	}

	public void append(String... strs) {
		for(String str : strs){
			expression.append(str);
		}
	}

	public void append(char... str) {
		expression.append(str);
	}

	public void append(char c) {
		expression.append(c);
	}
}
